﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using XsClient.Common;
using XsClient.Parsers;

namespace XsClient.Controls
{
    /// <summary>
    /// UCBooks.xaml 的交互逻辑
    /// </summary>
    public partial class UCBooks : UserControl
    {
        public UCBooks()
        {
            InitializeComponent();
            Init();
        }
        private UCCharpers ucCharpers = null;
        private UCBookContext ucContext = null;
        List<UCBookItem> ucBookItems = null;

        BaseResolver resolver = null;

        private void Init()
        {
            ucBookItems = new List<UCBookItem>();
            ucCharpers = new UCCharpers();
            ucCharpers.SelectCharpered += UcCharpers_SelectCharpered;
            panelChapers.Child = (ucCharpers);
            ucContext = new UCBookContext();
            ucContext.Prev += UcContext_Prev;
            ucContext.Next += UcContext_Next;
            borderContext.Child = ucContext;
            resolver = ResolverFactory.GetResolver();
            ShowLocalBooks();
        }

        private void ShowLocalBooks()
        {

            if (ucBookItems == null)
                ucBookItems = new List<UCBookItem>();
            //panelLocalBooks.Children.Clear();

            LocalBookList bookList = LocalBookList.Current;
            for (int i = 0; i < bookList.Books.Count; i++)
            {
                var item = bookList.Books[i];
                try
                {
                    UCBookItem ucItem = new UCBookItem() { Data = new BookInfo() { Name = item.Name, BaseUrl = item.FilePath, ReadChaperName = item.ReadChaperName, SourceID = -99 } };
                    ucItem.Click += UcItem_Click;
                    ucItem.RightMIClick += UcItem_RightMIClick;
                    // ucBookItems.Add(ucItem);
                    panelLocalBooks.Children.Add(ucItem);
                }
                catch (Exception ex)
                {
                    NewLife.Log.XTrace.WriteLine("加载本地书架失败");
                    NewLife.Log.XTrace.WriteException(ex);
                }
            }
        }

        private void UcItem_RightMIClick(UCBookItem book, int arg2)
        {
            try
            {
                BookInfo info = book.Data;
                for (int i = 0; i < BookList.Current.Books.Count; i++)
                {
                    var item = BookList.Current.Books[i];
                    if (item == null)
                        continue;
                    if (item.BaseUrl == info.BaseUrl)
                    {
                        if (arg2 == 0)
                        {//remove
                            BookList.Current.Books.RemoveAt(i);
                            panelLocalBooks.Children.Remove(book);
                        }
                        else if (arg2 == 1)
                        {
                            //up
                            if (i > 0)
                            {
                                var temp = BookList.Current.Books[i - 1];
                                BookList.Current.Books[i - 1] = item;
                                BookList.Current.Books[i] = temp;
                            }
                        }
                        else if (arg2 == -1)
                        {
                            //down
                            if (i < BookList.Current.Books.Count - 1)
                            {
                                var temp = BookList.Current.Books[i + 1];
                                BookList.Current.Books[i + 1] = item;
                                BookList.Current.Books[i] = temp;
                            }
                        }
                        else if (arg2 > 10)
                        {
                            //top
                            if (i > 0)
                            {
                                BookList.Current.Books.RemoveAt(i);
                                BookList.Current.Books.Insert(0, item);
                            }
                        }
                        else if (arg2 < -10)
                        {
                            //down
                            if (i < BookList.Current.Books.Count - 1)
                            {
                                BookList.Current.Books.RemoveAt(i);
                                BookList.Current.Books.Add( item);
                            }
                        }
                        BookList.Current.Save();
                        ShowBooks(BookList.Current.Books);
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                NewLife.Log.XTrace.WriteException(ex);
            }
        }

        private void UcContext_Next(object sender, EventArgs e)
        {
            ucCharpers.MoveNext();
        }

        private void UcContext_Prev(object sender, EventArgs e)
        {
            ucCharpers.MovePrev();
        }

        private void UcCharpers_SelectCharpered(BookInfo book, ChaperInfo chaper)
        {
            if (chaper != null)
            {
                try
                {
                    //selBook = book;
                    if (selBook != null)
                        selBook.ReadChaperName = chaper.Name;
                    SaveBookData();
                    labelTitle.Content = chaper.Name;
                    if (string.IsNullOrEmpty(chaper.Url) && chaper.StartLine > 0)
                    {
                        using (FileStream fs = File.OpenRead(bookPath))
                        {
                            long len = chaper.EndLine - chaper.StartLine;
                            if (len < 0)
                                len = fs.Length - chaper.StartLine;
                            byte[] data = new byte[len];
                            fs.Seek(chaper.StartLine, SeekOrigin.Begin);
                            fs.Read(data, 0, data.Length);
                            string context = Encoding.UTF8.GetString(data);
                            ucContext.ShowData("\r\n" + context + "\r\n");
                        }
                    }
                    else
                    {
                        labelTitle.Content = chaper.Name + "|" + chaper.Url;
                        Task.Factory.StartNew(() =>
                        {
                            try
                            {
                                var myresolver = ResolverFactory.GetResolver(chaper.SourceID);
                                string context = myresolver.GetContext(chaper.Url);
                                ucContext.ShowData("\r\n" + context + "\r\n");
                            }
                            catch (Exception ex)
                            {
                                NewLife.Log.XTrace.WriteException(ex);
                            }
                        });
                    }
                }
                catch (Exception ex)
                {
                    NewLife.Log.XTrace.WriteException(ex);
                }
            }
        }
        /// <summary>
        /// 保存阅读位置
        /// </summary>
        private void SaveBookData()
        {
            try
            {
                if (selBook == null)
                    return;
                BookInfo info = selBook;
                if (info.SourceID < 0)
                {
                    var current = LocalBookList.Current;
                    for (int i = 0; i < current.Books.Count; i++)
                    {
                        var item = current.Books[i];
                        if (info.Name == item.Name)
                        {
                            item.ReadChaperName = info.ReadChaperName;
                            break;
                        }
                    }

                    current.Save();
                    NewLife.Log.XTrace.WriteLine("local book num=" + LocalBookList.Current.Books.Count);
                }
                else
                {
                    for (int i = 0; i < BookList.Current.Books.Count; i++)
                    {
                        var item = BookList.Current.Books[i];
                        if (item == null)
                        {
                            BookList.Current.Books.RemoveAt(i);
                            i--;
                            continue;
                        }
                        if (info.Name == item.Name)
                        {
                            item.ReadChaperName = info.ReadChaperName;
                            item.BaseUrl = info.BaseUrl;
                            break;
                        }
                    }
                    BookList.Current.Save();
                }

            }
            catch (Exception ex)
            {
                NewLife.Log.XTrace.WriteException(ex);
            }
        }

        private void BtnSeach_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                string key = txtKey.Text.Trim();
                if (!string.IsNullOrEmpty(key))
                {
                    var books0 = resolver.Seach(key);
                    ShowBooks(books0);
                }
                else
                {
                    var books = resolver.FindBooks(resolver.Source.BaseUrl);

                    ShowBooks(books);
                }

            }
            catch (Exception ex)
            {
                NewLife.Log.XTrace.WriteException(ex);
            }
        }

        /// <summary>
        /// 选中书
        /// </summary>
        private BookInfo selBook = null;

        public void ShowBooks(List<BookInfo> books)
        {
            if (books != null)
            {
                ucBookItems.Clear();
                panelBooks.Children.Clear();
                var bookList = AppHelper.Instance.BookList;
                for (int i = 0; i < bookList.Books.Count; i++)
                {
                    var item = bookList.Books[i];
                    try
                    {
                        if (item == null)
                            continue;
                        UCBookItem ucItem = new UCBookItem() { Data = item };
                        ucItem.Click += UcItem_Click;
                        ucItem.RightMIClick += UcItem_RightMIClick;
                        ucBookItems.Add(ucItem);
                        panelBooks.Children.Add(ucItem);
                    }
                    catch (Exception ex)
                    {
                        NewLife.Log.XTrace.WriteLine(item.Name + "重复");
                        NewLife.Log.XTrace.WriteException(ex);
                    }
                }
                if (bookList.Books != books)
                    for (int i = 0; i < books.Count; i++)
                    {
                        var item = books[i];
                        try
                        {
                            if (item == null)
                                continue;
                            if (bookList.Books.Count(p => p != null && p.Name == item.Name) == 0)
                            {
                                bookList.Books.Add(item);
                            }

                            UCBookItem ucItem = new UCBookItem() { Data = item };
                            ucItem.Click += UcItem_Click;
                            ucItem.RightMIClick += UcItem_RightMIClick;
                            ucBookItems.Add(ucItem);
                            panelBooks.Children.Add(ucItem);
                        }
                        catch (Exception ex)
                        {
                            NewLife.Log.XTrace.WriteLine(item.Name + "重复");
                            NewLife.Log.XTrace.WriteException(ex);
                        }
                    }
                AppHelper.Instance.BookList.Save();

            }
        }
        private UCBookItem selectBook = null;
        private void UcItem_Click(object sender, EventArgs e)
        {
            if (selectBook != null)
                selectBook.ItemSelected = false;
            selectBook = sender as UCBookItem;

            if (selectBook != null)
            {
                BookInfo info = selectBook.Data;
                ShowChapers(info);
            }
        }
        private void ShowChapers(BookInfo info)
        {
            try
            {
                if (info == null)
                    return;
                selBook = info;
                ucCharpers.SetData(info);
                if (info.SourceID < 0)
                {
                    if (File.Exists(info.BaseUrl))
                    {
                        bookPath = info.BaseUrl;
                        Task.Factory.StartNew(new Action(() =>
                        {
                            try
                            {
                                using (FileStream fs = File.OpenRead(info.BaseUrl))
                                {
                                    string line = null;
                                    List<ChaperInfo> chapers = new List<ChaperInfo>();
                                    // fs.ReadTo("\n");
                                    line = fs.ReadLine(Encoding.UTF8);
                                    int i = 0;
                                    while (line != null)
                                    {
                                        if (string.IsNullOrEmpty(line))
                                        {
                                            line = fs.ReadLine(Encoding.UTF8);
                                            i++;
                                            continue;
                                        }
                                        if (line.Trim().StartsWith("【章节】"))
                                        {
                                            long position = fs.Position;
                                            ChaperInfo chaper = new ChaperInfo() { Name = line.Trim(), StartLine = position };
                                            if (chapers.Count > 0)
                                            {
                                                chapers[chapers.Count - 1].EndLine = position - 1;
                                            }
                                            chapers.Add(chaper);

                                            line = fs.ReadLine(Encoding.UTF8);
                                            i++;
                                            continue;
                                        }

                                        if (line.Trim().Contains("第") && (line.Contains("章") || line.Contains("节")))
                                        {
                                            int id = line.IndexOf("第");
                                            int iz = line.IndexOf("章");
                                            if (iz < 0)
                                                iz = line.IndexOf("节");
                                            if (id > 10 || id > iz)// || iz - id > 7)
                                            {
                                            }
                                            else
                                            {
                                                long position = fs.Position;
                                                ChaperInfo chaper = new ChaperInfo() { Name = line.Trim(), StartLine = position };
                                                if (chapers.Count > 0)
                                                {
                                                    chapers[chapers.Count - 1].EndLine = position - 1;
                                                }
                                                chapers.Add(chaper);
                                            }
                                        }
                                        line = fs.ReadLine(Encoding.UTF8);
                                        i++;
                                    }
                                    ucCharpers.SetData(chapers, info.ReadChaperName);

                                }

                            }
                            catch (Exception ex)
                            {
                                NewLife.Log.XTrace.WriteException(ex);

                            }

                        }));

                    }
                }
                else
                {
                    Task.Factory.StartNew(new Action(() =>
                    {
                        var myresolver = ResolverFactory.GetResolver(info.SourceID);
                        //ResolverFactory.GetResolver(info.BaseUrl);
                        string bookurl = info.BaseUrl;
                        var chapers = myresolver.FindChapers(ref bookurl);

                        if (chapers != null && chapers.Count > 0)
                        {
                            if (bookurl != info.BaseUrl && !bookurl.Contains(".html"))
                                info.BaseUrl = bookurl;
                        }
                        ucCharpers.SetData(chapers, info.ReadChaperName);

                    }));
                }
                //this.tabMenu.SelectedIndex = 1;

                tabMenu.Dispatcher.BeginInvoke(new Action(() =>
                {
                    tabMenu.SelectedItem = tabitemChaper;
                    tabitemChaper.Visibility = Visibility.Visible;
                }));
            }
            catch (Exception ex)
            {
                NewLife.Log.XTrace.WriteException(ex);
            }
        }

        private void BtnOpenBook_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                //string url = txtKey.Text.Trim();
                //var chapers = resolver.FindChapers(ref url);
                //ucCharpers.SetData(chapers, null);
                GUI.WinAddBook win = new GUI.WinAddBook();
                if (win.ShowDialog() == true)
                {
                    var bookList = AppHelper.Instance.BookList;
                    var item = bookList.Books[bookList.Books.Count - 1];
                    UCBookItem ucItem = new UCBookItem() { Data = item };
                    ucItem.Click += UcItem_Click;
                    ucItem.RightMIClick += UcItem_RightMIClick;
                    ucBookItems.Add(ucItem);
                    panelBooks.Children.Add(ucItem);
                }
            }
            catch (Exception ex)
            {
                NewLife.Log.XTrace.WriteException(ex);
            }
        }
        string bookPath = null;
        private void miImport_Click(object sender, RoutedEventArgs e)
        {

            try
            {
                Microsoft.Win32.OpenFileDialog fileDialog = new Microsoft.Win32.OpenFileDialog()
                {
                    Filter = "文本|*.txt"
                };
                if (fileDialog.ShowDialog() == true)
                {
                    string fileName = fileDialog.FileName;
                    AddLocalBooks(fileName);
                }
            }
            catch (Exception ex)
            {
                NewLife.Log.XTrace.WriteException(ex);
            }
        }
        private void AddLocalBooks(string fileName)
        {
            string name = System.IO.Path.GetFileNameWithoutExtension(fileName);
            LocalBookList bookList = LocalBookList.Current;
            if (bookList == null)
                bookList = new LocalBookList() { Books = new List<LocalBook>() };
            LocalBook book = new LocalBook() { Name = name, FilePath = fileName };
            if (!bookList.Books.Contains(book))
                bookList.Books.Add(book);
            bookList.Save();
            UCBookItem ucItem = new UCBookItem()
            {
                Data = new BookInfo()
                {
                    Name = name,
                    BaseUrl = fileName,
                    SourceID = -99
                }
            };
            ucItem.Click += UcItem_Click;

            ucItem.RightMIClick += UcItem_RightMIClick;
            panelLocalBooks.Children.Add(ucItem);
        }

        private void txtSearchKey_TextChanged(object sender, TextChangedEventArgs e)
        {
            string key = txtSearchKey.Text.Trim();
            FilterNode(key);
        }

        #region 过滤显示目录树
        /// <summary>
        /// 过滤目录显示
        /// </summary>
        /// <param name="key"></param>
        public void FilterNode(string key)
        {
            Task.Factory.StartNew(new Action(() =>
            {
                foreach (var item in ucBookItems)
                {
                    item.Dispatcher.BeginInvoke(new Action(() =>
                    {
                        ChangeTreeNodeVisibility(key, item);
                    }));
                }
            }));

        }
        /// <summary>
        /// 更改节点显示状态
        /// </summary>
        /// <param name="node"></param>
        private bool ChangeTreeNodeVisibility(string key, UCBookItem node)
        {
            bool isVisible = false;
            if (string.IsNullOrEmpty(key) || node.Data.Name.ToLower().Contains(key))
                isVisible = true;

            node.Visibility = isVisible ? Visibility.Visible : Visibility.Collapsed;
            return isVisible;
        }
        #endregion
    }
}
